OWL to Java generates a Java class model from an ontology defined using the W3C Web Ontology Language (OWL). The models are built by taking a specified list of OWL classes and creating Java classes for those OWL classes and their properties.
Mission statement:
Be a useful bridge between ontologies defined using open standards and object models
which are of immediate practical use in applications.
OWL to Java currently:
- Includes Java class mappings to OWL and RDF elements.
- Parses an OWL ontology into a map of java classes.
- Generates Java source from an OWL ontology in a local file.
- Runs as a Gradle Task
- Creates Java Source that compiles
- Publish to GitHub packages (0.1.1)
- None listed
- Graph DB annotations + graph example
- Lombok annotations
- Graphical viewer + example
- KDoc for code
- Java Docs for output
- Public website
- Publish Detekt and Kover reports from the Quality Report Build
- Consider progress against additional GitHub README badges.
- GitHub and public website analytics
- Donate option (linked to hosting account)
- Automate library updates
- Contributor guidelines
- Library Launch: Release to Maven Central
- Command-line execution from a shaded Jar
- RDBMS annotations + relational example
- Command line Examples
- Command-line execution from a Docker container
- Release to DockerHub
- HATEOAS REST API
- API docs with runnable swagger
- REST API examples
- Text based viewer
- Examples that scrape groups of sites using something like https://github.com/creative-mines/schemaorg4j
- Dashboard for Person data showing demographics and interpersonal connections
- Platform Launch: API based generation and viewer
- Kotlin idioms
- Profiling
- Non-failing report job and parallel multiple failing check job
- Auto-fix and submit PR
- Check and auto accept PR
- Inheritance by interface (via Lombok, or better in Kotlin?) and aggregation
- Handling of plurals as collections e.g. Person.parent is a relationship with multiplicity
- Load configuration set by name e.g. (com.example.OwlToJavaConfigSetSchemaOrg.setTaskConfig(this))
- Load configuration from Kotlin Script: https://kotlinexpertise.com/run-kotlin-scripts-from-kotlin-programs/
- Read multiple files (as an overlay)
- Pull strings into a multi-lingual template resource
- Add a parameterised fuzzy match (regex) instead of the OwlParser's match of the last 3 characters
- Extend one schema with another (by supporting mappings between schemas)
- @since versioned annotation on tests and auto-generated version history to CHANGELOG.md
- Review approach to guidance and help used here: https://github.com/researchgate/gradle-release
- Dependency org.simpleframework:simple-xml:2.7.1 is vulnerable
CVE-2017-1000190 9.1 Improper Restriction of XML External Entity Reference vulnerability pending CVSS allocation
Results powered by Checkmarx(c)
- đź«™ No valid plugin descriptors were found in META-INF/gradle-plugins
Example of Kotlin script evaluation
val script = compile("""listOf(1,2,3).joinToString(":")""")
assertEquals(listOf(1, 2, 3).joinToString(":"), script.eval())
val regenerate by registering(RegenerateOntologyTask::class) {
compile(File(Paths.get("${projectDir}/owl2java-schema.org.config").absolutePath()).load()).eval(this)
}
- Class and field definitions are generated based on OWL https://www.w3.org/TR/owl-guide/
- The ontology from https://schema.org/ is the primary use case for this project.
Build with tests which generate Java Sources:
% ./gradlew clean test
Starting a Gradle Daemon, 2 incompatible Daemons could not be reused, use --status for details
> Configure project :
WARNING: Unsupported Kotlin plugin version.
The `embedded-kotlin` and `kotlin-dsl` plugins rely on features of Kotlin `1.5.31` that might work differently than in the requested version `1.7.0-RC2`.
BUILD SUCCESSFUL in 22s
7 actionable tasks: 7 executed
%
The first 20 lines of Person Java object generated from a Parsed Schema.org OWL Schema describing humanity:
% head -30 ./build/generated-sources/uk/co/polycode/org/schema/Person.java
package uk.co.polycode.org.schema;
import java.lang.String;
import java.time.ZonedDateTime;
/**
* Person
*
* A person (alive, dead, undead, or fictional).
*
* This file was generated by OWL to Java as a transformation of the Schema.org schema Version 14.0.
* Schema.org is released under the Creative Commons Attribution-ShareAlike License (version 3.0).
* The Schema.org license is applicable to the generated source files and the license is available from
* "<a href="https://creativecommons.org/licenses/by-sa/3.0/">...</a>"
*/
public class Person extends Thing {
/**
* Where to find the definition of the OWL Class used to generate this Java class.
*/
public String isDefinedBy = "https://schema.org/Person";
/**
* An additional name for a Person, can be used for a middle name.
*/
public String additionalName;
/**
* Physical address of the item.
*/
public PostalAddress address;
// truncated...
}
Clone, build and publish to the local Maven repository (e.g. To use am unpublished Gradle Task fork in another project.):
% git clone <owl-to-java>
% cd <owl-to-java>
% ./gradlew build publishToMavenLocal
...BUILD SUCCESSFUL in 2m 35s...
% find ~/.m2 -name "owl-to-java*.jar"
.../.m2/repository/co/uk/polycode/owl-to-java/0.0.5-SNAPSHOT/owl-to-java-0.0.5-SNAPSHOT.jar
%
Generating Java sources with default settings using a Gradle Task called "regenerate" in Gradle's Kotlin DSL:
buildscript {
repositories {
mavenLocal() // OWL to Java Task would be in local
}
dependencies {
classpath("co.uk.polycode:owl-to-java:0.0.1-SNAPSHOT")
}
}
plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
}
tasks {
// Regenerate Java classes for schema.org using the OWL schema and default options
val regenerate by registering(uk.co.polycode.owltojava.RegenerateOntologyTask::class) {
outputs.upToDateWhen { false }
val srcMain: String = Paths.get("${projectDir}/../src/main").toFile().absolutePath
val sourceFileName = "schemaorg.owl"
lang = "en"
src = Paths.get("${srcMain}/resources/${sourceFileName}").toFile()
dest = Paths.get("${srcMain}/java").toFile()
javaBasePackage = "uk.co.polycode.ontology.with-defaults"
}
}
Generating Java sources with default settings using a Gradle Task called "regenerate" in Gradle's Groovy DSL:
import java.nio.file.Paths
buildscript {
repositories {
mavenLocal() // OWL to Java Task would be in local
mavenCentral()
}
dependencies {
classpath 'co.uk.polycode:owl-to-java:0.0.1-SNAPSHOT'
}
}
repositories {
mavenCentral()
}
// Override default library Task with:
// ./gradlew regenerate -PuseIncludedBuild=regenerate-lib-with-groovy
tasks.register("regenerate", uk.co.polycode.owltojava.RegenerateOntologyTask) { //regenerateTask ->
// Configure regenerateTask
regenerate.outputs.upToDateWhen {false}
def srcMain = Paths.get(projectDir.absolutePath + "/../src/main").toFile().absolutePath
def sourceFileName = "schemaorg.owl"
regenerate.lang = "en"
regenerate.src = Paths.get(srcMain + "/resources/" + sourceFileName).toFile()
regenerate.dest = Paths.get(projectDir.absolutePath + "/../build/generated-src-with-groovy").toFile()
regenerate.javaBasePackage = "uk.co.polycode.ontology.with-groovy"
}
Generating Java sources with primitive types defined settings using Kotlin:
val srcTestResources = "./src/test/resources"
val wholeOwlFilePath = Paths.get("${srcTestResources}/schemaorg.owl")
val javaSourceDirectoryPath = Paths.get("./build/generated-sources")
val javaBasePackage = "uk.co.polycode"
val primitivePropertyTypes = mapOf(
"https://schema.org/DataType" to Object::class.java.name,
"https://schema.org/Text" to String::class.java.name,
"https://schema.org/Time" to ZonedDateTime::class.java.name,
"https://schema.org/DateTime" to ZonedDateTime::class.java.name,
"https://schema.org/Date" to ZonedDateTime::class.java.name,
"https://schema.org/URL" to URL::class.java.name,
"https://schema.org/Integer" to BigInteger::class.java.name,
"https://schema.org/Float" to BigDecimal::class.java.name,
"https://schema.org/Number" to BigDecimal::class.java.name,
"https://schema.org/Boolean" to "java.lang.Boolean", // Boolean::class.java.name, unboxes to boolean.
)
val taskDelegateWithDefaults = RegenerateOntologyTaskDelegate(
src = wholeOwlFilePath.toFile(),
dest = javaSourceDirectoryPath.toFile(),
javaBasePackage = javaBasePackage).also {
it.primitivePropertyTypes = this.primitivePropertyTypes
}
taskDelegateWithDefaults.regenerateJavaSource()
Generating Java sources with settings tuned for this POJO library using a Gradle Task called "regenerate":
buildscript {
repositories {
mavenLocal() // OWL to Java Task would be in local
}
dependencies {
classpath("co.uk.polycode:owl-to-java:0.0.1-SNAPSHOT")
}
}
plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
}
tasks {
val regenerate by registering(uk.co.polycode.owltojava.RegenerateOntologyTask::class) {
outputs.upToDateWhen { false }
val srcMain: String = Paths.get("${projectDir}/../src/main").toFile().absolutePath
val sourceFileName = "schemaorg.owl"
lang = "en"
src = Paths.get("${srcMain}/resources/${sourceFileName}").toFile()
dest = Paths.get("${srcMain}/java").toFile()
javaBasePackage = "uk.co.polycode.ontology.lib"
licenceText = """
This file was generated by OWL to Java as a transformation of the Schema.org schema Version 14.0.
Schema.org is released under the Creative Commons Attribution-ShareAlike License (version 3.0).
The Schema.org license is applicable to the generated source files and the license is available from
https://creativecommons.org/licenses/by-sa/3.0/
"""
classes = listOf(
"https://schema.org/Person",
"https://schema.org/City",
"https://schema.org/CorporationX",
"https://schema.org/Project",
"https://schema.org/Book",
"https://schema.org/Article",
"https://schema.org/Fake"
)
primitivePropertyTypes = mapOf(
"https://schema.org/DataType" to Object::class.java.name,
"https://schema.org/Text" to String::class.java.name,
"https://schema.org/Time" to ZonedDateTime::class.java.name,
"https://schema.org/DateTime" to ZonedDateTime::class.java.name,
"https://schema.org/Date" to ZonedDateTime::class.java.name,
"https://schema.org/URL" to URL::class.java.name,
"https://schema.org/Integer" to BigInteger::class.java.name,
"https://schema.org/Float" to BigDecimal::class.java.name,
"https://schema.org/Number" to BigDecimal::class.java.name,
"https://schema.org/Boolean" to "java.lang.Boolean"
)
ignoredPropertyTypes = listOf(
"https://schema.org/Role"
)
prunedPropertyTypes = listOf(
"https://schema.org/Text",
"https://schema.org/URL"
)
ignoredSuperclasses = listOf<String>(
"https://www.w3.org/2000/01/rdf-schema#Class"
)
}
}
Owl to Java uses Trunk based Development https://www.flagship.io/git-branching-strategies/#trunk-based-development
An alternate branching strategy is likely to be required when there are multiple committers. While a low volume of commits and committers remains we have two paths to contribute to this project:
- Contact me via my GitHub profile (->website -> LinkedIn) and ask to be added to this project.
- Fork the repository then create a pull request.
Versioning is assisted by the Semantic Version Gradle Plugin, see: https://github.com/dipien/semantic-version-gradle-plugin
% ./gradlew printVersion
Version: 0.0.1-SNAPSHOT
% ./gradlew incrementVersion --versionIncrementType=PATCH
...
% ./gradlew printVersion
Version: 0.0.2-SNAPSHOT
%
To request a new feature:
- Add an item to the TODO list
(see above for paths to contribute to this project).
To add a new feature:
- Pick a feature from this
README.md
- Create at least one test for the feature, cut and paste the TODO list item into the test comment
- Build using
gradle build
- Commit code which passes
gradle clean check -PsafeBuildMode=false
- Get the commit hash using
git rev-parse HEAD
and add it to the test KDoc.
e.g.
/**
* Support all classes as the default
* @since("Commit hash: e66cfd2dedd09bb496ac852a630ee1fb62466533")
*/
@Test
fun testExpectedClassInSkeletonClassMapWithDefaults() {
// truncated...
}
To generate a dependency license report, use Gradle License Report plugin. See https://github.com/jk1/Gradle-License-Report
% ./gradlew generateLicenseReport
BUILD SUCCESSFUL in 3s
% head -5 build/reports/dependency-license/index.html
<html>
<head>
<title>
Dependency License Report for owl-to-java
%
OWL to Java is released under the Mozilla Public License, v. 2.0:
/**
* OWL to Java generates Source Code from the W3C Web Ontology Language (OWL)
* Copyright (C) 2022 Antony Cartwright, Polycode Limited
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Mozilla Public License, v. 2.0 for more details.
*/
OWL to Java uses the Schema from Schema.org which is released under the Creative Commons Attribution-ShareAlike License (version 3.0): https://creativecommons.org/licenses/by-sa/3.0/ Schema.org Version 14.0 is currently used and this can be downloaded from https://schema.org/docs/schemaorg.owl ( Release archive: https://github.com/schemaorg/schemaorg/tree/main/data/releases/14.0/ ) The following files are copies of or derivatives of Schema.org schemas:
./src/test/resources/schemaorg.owl - Schema.org Version 14.0: copy of https://schema.org/docs/schemaorg.owl
./src/test/resources/schemaorg-minimal-person.owl - Schema.org Version 10: Cut down copy orientated aroung Person
./src/test/resources/schemaorg-skeleton.owl - Schema.org Version 10: Cut down smallest meaningful ontology
Fragment of these files are referenced in OWL to Java source code and tests
OWL to Java used the Semantic Version Gradle Plugin which is released under the Apache License Version 2.0, January 2004: http://www.apache.org/licenses/ The following files are copies of or derivatives of Semantic Version Gradle Plugin source:
.github/workflows/increment_version.yml
- Copy of https://github.com/dipien/semantic-version-gradle-plugin/blob/master/.github/workflows/increment_version.yml